package dk.ucn.rejsealarmen;

import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.model.LatLng;

public class AlarmService extends Service {
	private static final String TAG = "AlarmService";

	MediaPlayer player;

	private int distance;
	private String xCoord;
	private String yCoord;
	private int hour;
	private int minute;
	private String message;

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {
		Toast.makeText(this, "AlarmService onCreate Called", Toast.LENGTH_LONG)
				.show();
		distance = 0;
		xCoord = "";
		yCoord = "";
		hour = 0;
		minute = 0;
		message = "";
		Log.d(TAG, "onCreate");

		player = MediaPlayer.create(this, R.raw.alarm);

		int status = GooglePlayServicesUtil
				.isGooglePlayServicesAvailable(getApplicationContext());

		if (status == ConnectionResult.SUCCESS) {
			Log.i(TAG, "Google Play services is available");

			String serviceName = Context.LOCATION_SERVICE; // get service
															// context
			locationManager = (LocationManager) getSystemService(serviceName); // Init
																				// LocationManager
																				// with
																				// service
																				// context

			Criteria criteria = new Criteria(); // Init Criteria
			criteria.setAccuracy(Criteria.ACCURACY_FINE); // Set accuracy for
															// criteria
			criteria.setPowerRequirement(Criteria.POWER_LOW); // Set
																// powerrequirements
			criteria.setAltitudeRequired(false); // Altitude not needed
			criteria.setBearingRequired(false); // Bearing not needed
			criteria.setSpeedRequired(false); // Speed not required
			criteria.setCostAllowed(true); // Indicates whether the provider is
											// allowed to incur monetary cost.

			// Set provider with defined criteria using locationManager
			provider = locationManager.getBestProvider(criteria, true);

		}

	}

	LocationManager locationManager; // LocationManager
	String provider;

	@Override
	public void onDestroy() {
		Toast.makeText(this, "AlarmService er stoppet", Toast.LENGTH_LONG)
				.show();
		Log.d(TAG, "onDestroy");
		player.stop();
	}

	@Override
	public void onStart(Intent intent, int startid) {
		Toast.makeText(this, "AlarmService er startet", Toast.LENGTH_LONG)
				.show();
		Log.d(TAG, "onStart");
	}

	public int onStartCommand(Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);
		// Toast.makeText(this, "onStartCommand called",
		// Toast.LENGTH_LONG).show();
		Bundle savedStateInstance = intent.getExtras();
		try {
			distance = savedStateInstance.getInt("distance");
			xCoord = String.valueOf(savedStateInstance.getInt("xCoord"));
			yCoord = String.valueOf(savedStateInstance.getInt("yCoord"));
			String destLongitude = xCoord; // x fra rejseplanen
			String destLatitude = yCoord; // y fra rejseplanen
			setDestination(destLatitude, destLongitude);
		} catch (Exception e1) {
			distance = -1;
		}
		try {
			hour = savedStateInstance.getInt("hour");
			minute = savedStateInstance.getInt("minute");
			message = savedStateInstance.getString("message");
			chosenMinutesBeforeArrival = savedStateInstance.getInt("chosenMinute");
			
			MyTimerTask myTask = new MyTimerTask();
			Timer myTimer = new Timer();

			myTimer.schedule(myTask, 0, 60000);

			// TODO
		} catch (Exception e) {
			hour = -1;
		}

		if (hour > 0) {
			Toast.makeText(this,
					"Valgt alarmtidspunkt: " + hour + ":" + minute,
					Toast.LENGTH_LONG).show();
		}
		if (distance > 0) {
			Toast.makeText(this, "Valgt afstand: " + distance + " meter.",
					Toast.LENGTH_LONG).show();
			locationManager.requestLocationUpdates(provider, 5000, 1,
					locationListener);
		}
		return 0;

	}
	int chosenMinutesBeforeArrival = 0;
	private LatLng destLatLng = null;

	private LatLng destination() {
		return destLatLng;
	}

	private void setDestination(String lat, String lng) {
		String latitude = lat;
		String longitude = lng;

		latitude = latitude.substring(0, 2) + "."
				+ latitude.substring(2, latitude.length());
		// Toast.makeText(this, latitude, Toast.LENGTH_LONG).show();
		int longitudeIntSubstring = Integer.valueOf(longitude.substring(0, 1));
		if (longitudeIntSubstring > 2) {
			longitude = longitude.substring(0, 1) + "."
					+ longitude.substring(1, longitude.length());

		} else {
			longitude = longitude.substring(0, 2) + "."
					+ longitude.substring(2, longitude.length());

		}
		destLatLng = new LatLng(Double.valueOf(latitude),
				Double.valueOf(longitude));
	}

	private final LocationListener locationListener = new LocationListener() {
		public void onLocationChanged(Location location) {
			double lat = location.getLatitude();
			double lng = location.getLongitude();
			LatLng myPos = new LatLng(Double.valueOf(lat), Double.valueOf(lng));
			calculateDistance(myPos, destination());

		}

		public void onProviderDisabled(String provider) {
		}

		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub

		}
	};

	public void checkTime() {

		int hourOfDay = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
		int minuteOfDay = Calendar.getInstance().get(Calendar.MINUTE);
		if (hour == hourOfDay && minute == minuteOfDay) {
			player.start();
			int arrivalHour = hour;
			int arrivalMinute = minute + chosenMinutesBeforeArrival;
			if(arrivalMinute >= 60){
				arrivalMinute = arrivalMinute - 60;
				arrivalHour = arrivalHour + 1;
			}
			String arrivalHourString = String.valueOf(arrivalHour);
			String arrivalMinuteString = String.valueOf(arrivalMinute);
			if(arrivalHour < 10){
				arrivalHourString = "0" + arrivalHourString;
			}
			if(arrivalMinute < 10){
				arrivalMinuteString = "0" + arrivalMinuteString;
			}
			
			String text = "Du ankommer kl " + arrivalHourString + ":" + arrivalMinuteString + ". " + message;

			Intent intent = new Intent(this, StopAlarm.class);
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.putExtra("alarmText", text);
			startActivity(intent);
		}
	}

	public void calculateDistance(LatLng startPos, LatLng endPos) {

		DecimalFormat newFormat = new DecimalFormat("####");

		int radius = 6371; // radius of earth in Km.

		double lat1 = startPos.latitude;
		double lat2 = endPos.latitude;
		double lon1 = startPos.longitude;
		double lon2 = endPos.longitude;

		double dLat = Math.toRadians(lat2 - lat1);
		double dLon = Math.toRadians(lon2 - lon1);

		double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
				+ Math.cos(Math.toRadians(lat1))
				* Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
				* Math.sin(dLon / 2);

		double c = 2 * Math.asin(Math.sqrt(a));

		double valueResult = radius * c;
		double valueResultInMeter = valueResult * 1000;
		int valueResultInDec = Integer.valueOf(newFormat
				.format(valueResultInMeter));

		Log.d(TAG, "************************************");
		Log.i(TAG, "ValueResult: " + valueResult);
		double km = valueResult / 1;
		Log.i(TAG, "km: " + km);
		int kmInDec = Integer.valueOf(newFormat.format(km));
		Log.i(TAG, "kmInDecFormat: " + kmInDec);

		if (km < 1) {
			kmInDec = 0;
		}
		double meter = (valueResult - kmInDec) * 1000;
		Log.i(TAG, "meter: " + meter);
		int meterInDec = Integer.valueOf(newFormat.format(meter));
		Log.i(TAG, "meterinDec: " + meterInDec);
		Log.i(TAG, valueResult + "\n" + kmInDec + "Km\n" + meterInDec
				+ " meter");

		if (valueResultInDec < distance) {
			player.start();
			String text = "Du ankommer om " + valueResultInDec + " meter";
			Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG)
					.show();
			Intent intent = new Intent(this, StopAlarm.class);
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.putExtra("alarmText", text);
			startActivity(intent);
		} else {
		}

		String msg = "Resterende afstand: " + valueResultInDec + " meter";

		Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
	}

	private class MyTimerTask extends TimerTask {

		@Override
		public void run() {
			checkTime();
		}

	}
}